﻿using System;
using System.Linq;
using System.Web.UI.WebControls;
using Medianamik.Core;
using Medianamik.Core.Sugar;
using Medianamik.Globalization;

namespace Medianamik.UI.TypeManagement
{
    //TODO: Validation des champs

    public partial class ManyToManyTypeManagement : BasePage
    {
        private Guid? _typeID; //Param optionnel

        protected void Page_Load(object sender, EventArgs e)
        {
            //Param optionnel == Édition

            #region Param TypeID

            var strTypeID = Request.QueryString[DefaultParamNames.TypeID];

            if (!String.IsNullOrEmpty(strTypeID) &&
                (!StringHelper.IsGuid(strTypeID, ref _typeID) || CurrentType == null))
            {
                Response.Redirect(ReturnURL);
            }

            #endregion

            if (!IsPostBack)
            {
                if (IsEdition)
                {
                    SetValues();
                }
            }
        }

        protected void btnSave_Click(object sender, EventArgs e)
        {
            if (IsValid)
            {
                //IMPORTANT : Ne pas dédoubler la validation
                //La validation s'effectue une fois seulement à l'aide des validateurs de .Net (Client & Server Side)

                //Vérifier que le nom du type est unique
                if (((IsEdition && CurrentType.Name != txtTypeName.Text) || !IsEdition)
                    && NodeTypeManager.NodeTypeExists(txtTypeName.Text))
                {
                    //TODO: Afficher message indiquant que le type existe déjà
                }
                else
                {
                    //Pas nécessaire de vérifier l'unicité des noms des propriétés
                    //Un validateur .Net (comparaison) doit seulment s'assurer que
                    //les deux noms des propriétés sont différents

                    #region PrimaryPropertyOne

                    #region Name

                    var propertyOneName = PropertyOne.PropertyName.Trim();
                    var propertyOneGroup = PropertyOne.GroupName.Trim();

                    #endregion

                    #region Default Values

                    Guid? propertyOnePrimaryMedianamikControlID = null;
                    int? propertyOnePrimaryMedianamikControlWidth = null;
                    int? propertyOnePrimaryMedianamikControlHeight = null;

                    var propertyOnePrimaryTreeRootNodeId = default(Guid?);

                    #endregion

                    #region Primary Type

                    var propertyOnePrimaryTypeID = PropertyOne.PrimaryTypeID;

                    #endregion

                    #region Primary Property

                    var propertyOnePrimaryPropertyID = PropertyOne.PrimaryPropertyID;

                    #endregion

                    #region Primary Medianamik Control

                    var mkControlOne = PropertyOne.PrimaryMedianamikControlID.HasValue
                                           ? ConfigManager.GetMedianamikControl(
                                               PropertyOne.PrimaryMedianamikControlID.Value)
                                           : default(MedianamikControl);
                    if (mkControlOne != null)
                    {
                        propertyOnePrimaryMedianamikControlID = mkControlOne.ID;
                        propertyOnePrimaryMedianamikControlHeight = PropertyOne.PrimaryMedianamikControlHeigth;
                        propertyOnePrimaryMedianamikControlWidth = PropertyOne.PrimaryMedianamikControlWidth;
                        if (PropertyOne.PrimaryTreeRootNodeId.HasValue)
                        {
                            propertyOnePrimaryTreeRootNodeId = PropertyOne.PrimaryTreeRootNodeId;
                        }
                    }

                    #endregion

                    #endregion

                    #region PrimaryPropertyTwo

                    #region Name

                    var propertyTwoName = PropertyTwo.PropertyName.Trim();
                    var propertyTwoGroup = PropertyTwo.GroupName.Trim();

                    #endregion

                    #region Default Values

                    Guid? propertyTwoPrimaryMedianamikControlID = null;
                    int? propertyTwoPrimaryMedianamikControlWidth = null;
                    int? propertyTwoPrimaryMedianamikControlHeight = null;
                    var propertyTwoPrimaryTreeRootNodeId = default(Guid?);

                    #endregion

                    #region Primary Type

                    var propertyTwoPrimaryTypeID = PropertyTwo.PrimaryTypeID;

                    #endregion

                    #region Primary Property

                    var propertyTwoPrimaryPropertyID = PropertyTwo.PrimaryPropertyID;

                    #endregion

                    #region Primary Medianamik Control

                    var mkControlTwo = PropertyTwo.PrimaryMedianamikControlID.HasValue
                                           ? ConfigManager.GetMedianamikControl(
                                               PropertyTwo.PrimaryMedianamikControlID.Value)
                                           : default(MedianamikControl);
                    if (mkControlTwo != null)
                    {
                        propertyTwoPrimaryMedianamikControlID = mkControlTwo.ID;
                        propertyTwoPrimaryMedianamikControlHeight = PropertyTwo.PrimaryMedianamikControlHeigth;
                        propertyTwoPrimaryMedianamikControlWidth = PropertyTwo.PrimaryMedianamikControlWidth;
                        if (PropertyTwo.PrimaryTreeRootNodeId.HasValue)
                        {
                            propertyTwoPrimaryTreeRootNodeId = PropertyTwo.PrimaryTreeRootNodeId;
                        }
                    }

                    #endregion

                    #endregion

                    if (IsEdition)
                    {
                        CurrentType.IsManyToMany = true; //Important
                        CurrentType.Name = txtTypeName.Text;
                        CurrentType.Description = txtTypeDescription.Text;
                        CurrentType.IsGenerated = true;
                        CurrentType.IsAbstract = false;
                        CurrentType.IsSystem = chkIsSystem.Checked;

                        #region PrimaryPropertyOne

                        CurrentType.Properties[0].Name = propertyOneName;
                        CurrentType.Properties[0].GroupName = propertyOneGroup;
                        CurrentType.Properties[0].PrimaryTypeID = propertyOnePrimaryTypeID;
                        CurrentType.Properties[0].PrimaryPropertyID = propertyOnePrimaryPropertyID;
                        CurrentType.Properties[0].PrimaryMedianamikControlID = propertyOnePrimaryMedianamikControlID;
                        CurrentType.Properties[0].PrimaryMedianamikControlInfo =
                            new MedianamikControlInfo(propertyOnePrimaryMedianamikControlWidth,
                                                      propertyOnePrimaryMedianamikControlHeight,
                                                      propertyOnePrimaryTreeRootNodeId);
                        CurrentType.Properties[0].IsLanguageNeutral = true; //

                        #endregion

                        #region PrimaryPropertyTwo

                        CurrentType.Properties[1].Name = propertyTwoName;
                        CurrentType.Properties[1].GroupName = propertyTwoGroup;
                        CurrentType.Properties[1].PrimaryTypeID = propertyTwoPrimaryTypeID;
                        CurrentType.Properties[1].PrimaryPropertyID = propertyTwoPrimaryPropertyID;
                        CurrentType.Properties[1].PrimaryMedianamikControlID = propertyTwoPrimaryMedianamikControlID;
                        CurrentType.Properties[1].PrimaryMedianamikControlInfo =
                            new MedianamikControlInfo(propertyTwoPrimaryMedianamikControlWidth,
                                                      propertyTwoPrimaryMedianamikControlHeight,
                                                      propertyTwoPrimaryTreeRootNodeId);
                        CurrentType.Properties[1].IsLanguageNeutral = true; //

                        #endregion
                    }
                    else
                    {
                        _currentType = new NodeType(txtTypeName.Text, false,
                                                    true, false, chkIsSystem.Checked,
                                                    null, true, null, null, null, null)
                                           {
                                               Description = txtTypeDescription.Text,
                                               IsManyToMany = true
                                           };

                        #region PrimaryPropertyOne

                        var controlSettingsOne = new MedianamikControlInfo(propertyOnePrimaryMedianamikControlWidth
                                                                           , propertyOnePrimaryMedianamikControlHeight
                                                                           , propertyOnePrimaryTreeRootNodeId);

                        var prop1 = CurrentType.AddProperty(propertyOneName, null, null, false /*HaveTooltip*/, true
                                                            /*IsLanguageNeutral*/,
                                                            false, false, null, propertyOneGroup, null,
                                                            null, DataTypes.UniqueIdentifier,
                                                            propertyOnePrimaryTypeID, propertyOnePrimaryPropertyID,
                                                            propertyOnePrimaryMedianamikControlID, controlSettingsOne,
                                                            DataTypes.UniqueIdentifier, default(Guid?));

                        #endregion

                        #region PrimaryPropertyTwo

                        var controlSettingsTwo = new MedianamikControlInfo(propertyTwoPrimaryMedianamikControlWidth
                                                                           , propertyTwoPrimaryMedianamikControlHeight
                                                                           , propertyTwoPrimaryTreeRootNodeId);

                        var prop2 = CurrentType.AddProperty(propertyTwoName, null, null, false /*HaveTooltip*/, true
                                                            /*IsLanguageNeutral*/,
                                                            false, false, null, propertyTwoGroup, null, null,
                                                            DataTypes.UniqueIdentifier,
                                                            propertyTwoPrimaryTypeID, propertyTwoPrimaryPropertyID,
                                                            propertyTwoPrimaryMedianamikControlID
                                                            , controlSettingsTwo, DataTypes.UniqueIdentifier,
                                                            default(Guid?));

                        #endregion
                    }

                    try
                    {
                        NodeTypeManager.SaveType(CurrentType);
                        // Note: Ne pas faire de Response.Redirect dans un try/catch.
                        // C'est très mal.
                    }
                    catch (Exception)
                    {
                        //TODO: Catcher les différentes exceptions Médianamik et afficher les messages correspondant
                        throw;
                    }
                    Translator.CreateResource("TypeManagement", CurrentType.ID + "_Label", TypeNameTranslations.Values);
                    Translator.CreateResource("TypeManagement", CurrentType.Properties[0].ID + "_Label",
                                              PropertyOne.Translations);
                    Translator.CreateResource("TypeManagement", CurrentType.Properties[1].ID + "_Label",
                                              PropertyTwo.Translations);

                    Response.Redirect(ReturnURL);
                }
            }
        }

        protected void cvPropertyNames_ServerValidate(object source, ServerValidateEventArgs args)
        {
            args.IsValid = (PropertyOne.PropertyName.ToLower().Trim() != PropertyTwo.PropertyName.ToLower().Trim());
        }

        private NodeType _currentType;

        public NodeType CurrentType
        {
            get
            {
                if (_currentType == null && _typeID.HasValue)
                {
                    _currentType = NodeTypeManager.GetNodeType(_typeID.Value);
                }

                return _currentType;
            }
        }

        private string _returnURL;

        public string ReturnURL
        {
            get
            {
                if (_returnURL == null)
                {
                    _returnURL = "manytomanytypelist.aspx";
                }

                return _returnURL;
            }
        }

        private bool IsEdition
        {
            get { return _typeID.HasValue; }
        }

        private void SetValues()
        {
            //Bloquer la modification de certaines propriétés une fois que le type est utilisé

            txtTypeName.Text = CurrentType.Name;
            txtTypeDescription.Text = CurrentType.Description;

            //chkIsGenerated.Checked = CurrentType.IsGenerated;
            chkIsSystem.Checked = CurrentType.IsSystem;

            PropertyOne.SetValues(CurrentType.Properties[0]);
            PropertyOne.IsEditing = true;

            PropertyTwo.SetValues(CurrentType.Properties[1]);
            PropertyTwo.IsEditing = true;

            TypeNameTranslations.Values = Translator.GetResources("TypeManagement",
                                                                  CurrentType.ID + "_Label",
                                                                  ConfigManager.GetMedianamikCultures().Select(
                                                                      c => c.CultureInfo));
        }
    }
}